# -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

from openerp.osv import osv, fields
from openerp import SUPERUSER_ID
from openerp.tools.translate import _
import openerp.addons.decimal_precision as dp
from datetime import datetime
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT, DEFAULT_SERVER_DATE_FORMAT


class return_move_line(osv.osv_memory):
    """销售和采购退换货共用一个 产品行表"""
    _name = "return.move.line"
    _rec_name = 'product_id'
    
    _columns = {
        'product_id': fields.many2one('product.product', string="产品", required=True),
        'max_quantity': fields.float("最大数量", digits_compute=dp.get_precision('Product Unit of Measure')),
        'quantity': fields.float("数量", digits_compute=dp.get_precision('Product Unit of Measure'), required=True),
        'sale_wizard_id': fields.many2one('sale.return.move', string="Wizard"),
        'purchase_wizard_id': fields.many2one('purchase.return.move', string="Wizard"),
        'move_id': fields.many2one('stock.move', u"库存移动"),
    }

    def onchange_quantity(self, cr, uid, ids, quantity, max_quantity, context=None):
        if quantity > 0:
            if quantity > max_quantity:
                return {
                    'warning': {'title': u'错误！', 'message': u'输入的退货数超出！'},
                    'value': {'quantity': max_quantity}
                }
        else:
            return {
                'warning': {'title': u'错误！', 'message': u'数量必须大于零!'},
                'value': {'quantity': 1}
            }

class change_product_line(osv.osv_memory):
    _name = "change.product.line"
    _rec_name = 'product_id'

    _columns = {
        'product_id': fields.many2one('product.product', string="产品", required=True, domain=[('type', '!=', 'service')]),
        'quantity': fields.float("数量", digits_compute=dp.get_precision('Product Unit of Measure'), required=True),
        'note': fields.char(u'销售备注'),
        'return_service_wizard_id': fields.many2one('sale.return.move', string="Wizard"),
        'sale_wizard_id': fields.many2one('sale.return.move', string="Wizard"),
        'purchase_wizard_id': fields.many2one('purchase.return.move', string="Wizard"),
        'price_unit': fields.float(u'单价'),
    }
    
    def onchange_product_id(self, cr,uid, ids, product_id, so_id, context=None):
        """当修改换货产品行时同时改变对应的价格！"""
        product_row = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
        line_obj = self.pool.get('sale.order.line')
        line_ids =[line.get('product_id', [False, False])[0] for
                   line in line_obj.search_read(cr, uid, [('order_id', '=', so_id)], ['product_id'], context=context)]
        if product_id in line_ids:
            return {'value': {'price_unit': product_row.lst_price}}
        elif product_id:
            return {'warning': {'title': u'警告', 'message': u'要退货的产品不在对应销售订单里面！'},
                    'value': {'product_id': False}}


class sale_return_move(osv.osv_memory):
    _name = 'sale.return.move'
    _description = 'Return Picking'
    _columns = {
        'product_return_moves': fields.one2many('return.move.line', 'sale_wizard_id', 'Moves'),
        'move_dest_exists': fields.boolean('Chained Move Exists', readonly=True, help="Technical field used to hide help tooltip if not needed"),
        'change_product_lines': fields.one2many('change.product.line', 'sale_wizard_id', u'换货产品'),
        'return_product_lines': fields.one2many('change.product.line', 'return_service_wizard_id', u'退回服务类产品'),
        'is_exchange': fields.boolean(u'是否换货单'),
        'so_id': fields.many2one('sale.order', u'销售订单')
    }
    
    _defaults = {
        'so_id': lambda self, cr, uid, context=None: context.get('active_id')
    }

    def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
        return_vals = super(sale_return_move, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type,
                                                                     context=context, toolbar=toolbar, submenu=submenu)
        can_return_move_product = []
        if context and context.get('active_ids', False):
            if len(context.get('active_ids')) > 1:
                raise osv.except_osv(_('警告!'), _("只能选择一个销售订单!"))
        record_id = context and context.get('active_ids', False) or []
        order_obj = self.pool.get('sale.order')
        for order_row in order_obj.browse(cr, uid, record_id, context=context):
            if order_row.is_card:
                raise osv.except_osv(u'警告!', u"卡券订单请用 ‘卡券退货按钮进行退货’!")
            if order_row.is_return or order_row.is_exchange:
                raise osv.except_osv(_('警告!'), _("退换货的销售订单不能再次退货!"))
        pick_obj = self.pool.get('stock.picking')
        picks = pick_obj.search(cr, SUPERUSER_ID, [('so_id', 'in', record_id), ('picking_type_id.code', '=', 'outgoing'),
                                          ('state', '=', 'done')], context=context)
        picking_objs = pick_obj.browse(cr, SUPERUSER_ID, picks, context=context)
        for pick in picking_objs:
            for move in pick.move_lines:
                # 已退货数量 通过统计已经退货的数量来改变
                return_qty = sum([move_row.product_uom_qty for move_row in move.returned_move_ids
                                  if move_row.state != 'cancel'])
                if return_qty == move.product_uom_qty:
                    continue
                can_return_move_product.append({'product_id': move.product_id.id})
        service_order = [line.product_id.id for line in order_row.order_line if line.product_id.type == 'service']
        if len(can_return_move_product) == 0 and len(service_order) == 0:
            raise osv.except_osv(_('警告!'), _("没有产品需要退货!"))
        return return_vals
    
    def default_get(self, cr, uid, fields, context=None):
        can_return_move_product = []
        if context and context.get('active_ids', False):
            if len(context.get('active_ids')) > 1:
                raise osv.except_osv(_('警告!'), _("只能选择一个销售订单!"))
        res = super(sale_return_move, self).default_get(cr, uid, fields, context=context)
        record_id = context and context.get('active_ids', False) or []
        uom_obj = self.pool.get('product.uom')
        pick_obj = self.pool.get('stock.picking')
        picks = pick_obj.search(cr, SUPERUSER_ID, [('so_id', 'in', record_id), ('picking_type_id.code', '=', 'outgoing'),
                                          ('state', '=', 'done')], context=context)
        picking_objs = pick_obj.browse(cr, SUPERUSER_ID, picks, context=context)
        chained_move_exist = False
        for pick in picking_objs:
            for picking_move in pick.move_lines:
                # 已退货数量
                return_qty = sum([return_move_row.product_uom_qty for return_move_row in picking_move.returned_move_ids
                                  if return_move_row.state != 'cancel'])
                if return_qty == picking_move.product_uom_qty:
                   continue
                qty = uom_obj._compute_qty(cr, SUPERUSER_ID, picking_move.product_id.uom_id.id,
                                           picking_move.product_uom_qty-return_qty, picking_move.product_uom.id)
                can_return_move_product.append({'product_id': picking_move.product_id.id,
                                                'quantity': qty,
                                                'max_quantity': qty,
                                                'move_id': picking_move.id})
        if 'product_return_moves' in fields:
            res.update({'product_return_moves': can_return_move_product})
        if 'move_dest_exists' in fields:
            res.update({'move_dest_exists': chained_move_exist})
        return res

    def create_return_sale_order(self, cr, uid, order_row, data, context=None):
        order_obj = self.pool.get('sale.order')
        order_row.write({'is_has_return_change': True}) # is_has_return_change要设置为copy=False
        so_id = order_obj.copy(cr, uid, order_row.id, {
            'is_return': not data['is_exchange'],
            'is_exchange': data['is_exchange'],
            'origin_so_id': order_row.id,
            'order_line': 'NULL'
        })
        return so_id

    def create_sale_line(self, cr, uid, move, data_get, new_qty,
                              new_picking, pick_type_id, move_dest_id, pick, so_id,
                              change=False, change_picking=False, context=None):
        so_line_id = self.pool.get('sale.order.line').create(cr, uid, {
            'product_id': data_get.product_id.id,
            'product_uom_qty': new_qty if change else -new_qty,
            'name': data_get.product_id.name,
            'delivered_qty': new_qty,
            'order_id': so_id,
            'sale_note': change and data_get.note or move.note or '',
            'price_unit': change and data_get.price_unit or move.so_line_id.price_unit,
            'product_uos_qty': (new_qty if change else -new_qty) * move.product_uos_qty / move.product_uom_qty,
            'state': 'draft',
        }, context=context)
        return so_line_id

    def create_service_sale_line(self, cr,  uid, change_product_row, so_id, context=None):
        so_line_id = self.pool.get('sale.order.line').create(cr, uid, {
            'product_id': change_product_row.product_id.id,
            'product_uom_qty': -change_product_row.quantity,
            'name': change_product_row.product_id.name,
            'delivered_qty': 0,
            'order_id': so_id,
            'sale_note': change_product_row.note,
            'product_uos_qty': change_product_row.quantity,
            'state': 'draft',
        }, context=context)
        return so_line_id

    def create_move_sale_line(self, cr, uid, move, data_get, new_qty,
                              new_picking, pick_type_id, move_dest_id, pick, so_id,
                              change=False, change_picking=False, context=None):
        move_obj = self.pool.get('stock.move')
        so_line_id = self.create_sale_line(cr, uid, move, data_get, new_qty,
                              new_picking, pick_type_id, move_dest_id, pick, so_id,
                              change=change, change_picking=change_picking, context=context)
        move_obj.copy(cr, SUPERUSER_ID, move.id, {
            'product_id': data_get.product_id.id,
            'name': '[%s] %s' % (data_get.product_id.default_code, data_get.product_id.name),
            'product_uom_qty': new_qty,
            'product_uos_qty': new_qty * move.product_uos_qty / move.product_uom_qty,
            'picking_id': change_picking or new_picking,
            'state': 'draft',
            'so_line_id': so_line_id,
            'location_id': move.location_id.id if change else move.location_dest_id.id,
            'location_dest_id': move.location_dest_id.id if change else move.location_id.id,
            'picking_type_id': pick_type_id,
            'warehouse_id': pick.picking_type_id.warehouse_id.id,
            'origin_returned_move_id': False if change else move.id,
            'procure_method': 'make_to_stock',
            'move_dest_id': False if change else move_dest_id,
            'prod_spec': False,
        })
        return True

    def all_raise(self, cr, uid, sale_return_row, context=None):
        if not sale_return_row.product_return_moves and not sale_return_row.return_product_lines:
            raise osv.except_osv(_(u'警告 !'), _(u"没有要退回的产品！"))
        if not sale_return_row.change_product_lines and sale_return_row.is_exchange:
            raise osv.except_osv(_(u'警告 !'), _(u"没有填写要换取的产品！"))

    def onchange_is_change(self, cr, uid, ids, is_exchange, change_product_lines, context=None):
        """当取消点击换货单后，清空换货产品行"""
        if not is_exchange:
            return {'value': {'change_product_lines': [(6, 0, [])]}}

    def _create_returns(self, cr, uid, ids, context=None):
        """写的时候不认真，跑神了，要仔细检查。
        这个方法是换货的关键地方
        """
        if context is None:
            context = {}
        record_id = context and context.get('active_ids', False) or False
        move_obj = self.pool.get('stock.move')
        pick_obj = self.pool.get('stock.picking')
        order_row = self.pool.get('sale.order').browse(cr, uid, record_id, context=context)
        picks = pick_obj.search(cr, SUPERUSER_ID, [('so_id', 'in', record_id),
                                                   ('picking_type_id.code', '=', 'outgoing'),
                                                   ('state', '=', 'done')], context=context)
        pick_rows = pick_obj.browse(cr, SUPERUSER_ID, picks, context=context)
        # 直接参考的官方退货的方法， 居然是用的read 导致后边写法上比较混乱
        sale_return_row = self.browse(cr, uid, ids[0], context=context)
        self.all_raise(cr, uid, sale_return_row, context=context)
        returned_lines, new_picking, move = 0, False, False
        so_id = self.create_return_sale_order(cr, uid, order_row, sale_return_row, context=context)
        order_row = self.pool.get('sale.order').browse(cr, uid, so_id, context=context)
        # 不管是出入库的picking 都要用到这一部分的 参数
        common_picking_val = {
            'consignee': order_row.consignee, 'street': order_row.street,
            'zip': order_row.zip, 'mobile_number': order_row.mobile_number,
            'phone_number': order_row.phone_number, 'province_id': order_row.province_id.id,
            'city_id': order_row.city_id.id, 'county_id': order_row.county_id.id
        }
        for pick in pick_rows:
            # 为以后可能多单同时退货做 提前的与留量
            moves_to_unreserve = []
            for move in pick.move_lines:
                to_check_moves = [move.move_dest_id] if move.move_dest_id.id else []
                while to_check_moves:
                    current_move = to_check_moves.pop()
                    if current_move.state not in ('done', 'cancel') and current_move.reserved_quant_ids:
                        moves_to_unreserve.append(current_move.id)
                    split_move_ids = move_obj.search(cr, uid, [('split_from', '=', current_move.id)], context=context)
                    if split_move_ids:
                        to_check_moves += move_obj.browse(cr, uid, split_move_ids, context=context)
            if moves_to_unreserve:
                move_obj.do_unreserve(cr, uid, moves_to_unreserve, context=context)
                move_obj.write(cr, uid, moves_to_unreserve, {'move_orig_ids': False}, context=context)
                
            pick_type_id = pick.picking_type_id.return_picking_type_id and \
                           pick.picking_type_id.return_picking_type_id.id or pick.picking_type_id.id
            if not new_picking and sale_return_row.product_return_moves:
                common_picking_val.update({
                    'move_lines': [], 'picking_type_id': pick_type_id,
                    'delivery_done_time': False,
                    'state': 'draft', 'origin': order_row.name})
                new_picking = pick_obj.copy(cr, SUPERUSER_ID, pick.id, common_picking_val, context=context)
                if sale_return_row.is_exchange:
                    # 创建 换货产品的picking
                    del common_picking_val['picking_type_id']
                    change_picking = pick_obj.copy(cr, SUPERUSER_ID, pick.id, common_picking_val, context=context)

        for return_move_row in sale_return_row.product_return_moves:
            template_move_row = return_move_row.move_id
            if not move:
                raise osv.except_osv(_(u'警告 !'), _(u"您已经手动生成了产品行，请删除他们并继续操作！"))
            new_qty = return_move_row.quantity
            if new_qty:
                if template_move_row.origin_returned_move_id.move_dest_id.id and \
                                template_move_row.origin_returned_move_id.move_dest_id.state != 'cancel':
                    move_dest_id = template_move_row.origin_returned_move_id.move_dest_id.id
                else:
                    move_dest_id = False
                returned_lines += 1
                self.create_move_sale_line(cr, uid, template_move_row, return_move_row, new_qty,
                          new_picking, pick_type_id, move_dest_id, pick, so_id, context=context)

        for change_product_row in sale_return_row.return_product_lines:
            # template_move_row 用来获取 退货move 上的一些信息
            if change_product_row.quantity > 0:
                returned_lines += 1
                self.create_service_sale_line(cr, uid, change_product_row, so_id, context=context)

        for change_product_row in sale_return_row.change_product_lines:
            # template_move_row 用来获取 退货move 上的一些信息
            if change_picking and change_product_row.quantity > 0:
                 self.create_move_sale_line(cr, uid, return_move_row.move_id, change_product_row,
                                            change_product_row.quantity, False, pick_type_id, move_dest_id, pick,
                                            so_id, change=True, change_picking=change_picking, context=context)
        # if move:  #没有实际意义但是还影响了原有的功能
        #     pick_obj.write(cr, uid, new_picking, {'origin_picking_id': move.picking_id.id}, context=context)
        if not returned_lines:
            raise osv.except_osv(_(u'警告!'), _(u"请保留至少一个非零的产品行！"))
        if new_picking:
            pick_obj.action_confirm(cr, SUPERUSER_ID, [new_picking], context=context)
            pick_obj.action_assign(cr, SUPERUSER_ID, [new_picking], context)
        return so_id

    def create_returns(self, cr, uid, ids, context=None):
        sale_id = self._create_returns(cr, uid, ids, context=context)
        return {
            'domain': "[('id', 'in', [" + str(sale_id) + "])]",
            'name': u'退货销售订单',
            'view_type': 'form',
            'view_mode': 'tree,form',
            'res_model': 'sale.order',
            'type': 'ir.actions.act_window',
        }

class purchase_return_move(osv.osv_memory):
    _name = 'purchase.return.move'
    _description = 'Return Picking'
    _columns = {
        'product_return_moves': fields.one2many('return.move.line', 'purchase_wizard_id', 'Moves'),
        'move_dest_exists': fields.boolean('Chained Move Exists', readonly=True,
                                           help="Technical field used to hide help tooltip if not needed"),
    }

    def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
        return_vals = super(purchase_return_move, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type,
                                                                    context=context, toolbar=toolbar,
                                                                    submenu=submenu)
        result1 = []
        if context and context.get('active_ids', False):
            if len(context.get('active_ids')) > 1:
                raise osv.except_osv(_('警告!'), _("只能选择一个销售订单!"))
        record_id = context and context.get('active_ids', False) or []
        pick_obj = self.pool.get('stock.picking')
        picks = pick_obj.search(cr, SUPERUSER_ID,
                                [('po_id', 'in', record_id), ('picking_type_id.code', '=', 'incoming'),
                                 ('state', '=', 'done')], context=context)
        order_obj = self.pool.get('purchase.order')
        for order_row in order_obj.browse(cr, uid, record_id,context=context):
            if order_row.is_return or order_row.is_exchange:
                raise osv.except_osv(_('警告!'), _("退换货的采购订单不能次退货!"))
        picking_objs = pick_obj.browse(cr, SUPERUSER_ID, picks, context=context)
        for pick in picking_objs:
            for move in pick.move_lines:
                return_qty = sum([move_row.product_uom_qty for move_row in move.returned_move_ids
                                  if move_row.state != 'cancel'])
                if return_qty == move.product_uom_qty:
                    continue
                result1.append({'product_id': move.product_id.id})
        if len(result1) == 0:
            raise osv.except_osv(_('警告!'), _("没有产品需要退货!"))
        return return_vals

    def default_get(self, cr, uid, fields, context=None):
        result1 = []
        if context and context.get('active_ids', False):
            if len(context.get('active_ids')) > 1:
                raise osv.except_osv(_('警告!'), _("只能选择一个采购订单!"))
        res = super(purchase_return_move, self).default_get(cr, uid, fields, context=context)
        record_id = context and context.get('active_ids', False) or []
        uom_obj = self.pool.get('product.uom')
        pick_obj = self.pool.get('stock.picking')
        picks = pick_obj.search(cr, SUPERUSER_ID,
                                [('po_id', 'in', record_id), ('picking_type_id.code', '=', 'incoming'),
                                 ('state', '=', 'done')], context=context)
        picking_objs = pick_obj.browse(cr, SUPERUSER_ID, picks, context=context)
        chained_move_exist = False
        for pick in picking_objs:
            for move in pick.move_lines:
                # 已退货数量
                return_qty = sum([move_row.product_uom_qty for move_row in move.returned_move_ids
                                  if move_row.state != 'cancel'])
                if return_qty == move.product_uom_qty:
                    continue
                qty = uom_obj._compute_qty(cr, SUPERUSER_ID, move.product_id.uom_id.id,
                                           move.product_uom_qty - return_qty, move.product_uom.id)
                result1.append({'product_id': move.product_id.id, 'quantity': qty,
                                'max_quantity': qty, 'move_id': move.id})
        if len(result1) == 0:
            raise osv.except_osv(_('警告!'), _("没有产品需要退货!"))
        if 'product_return_moves' in fields:
            res.update({'product_return_moves': result1})
        if 'move_dest_exists' in fields:
            res.update({'move_dest_exists': chained_move_exist})
        return res

    def create_return_purchase_order(self, cr, uid, order_row, context=None):
        order_obj = self.pool.get('purchase.order')
        po_id = order_obj.copy(cr, uid, order_row.id, {
            'is_return': True,
            'invoiced': False,
            'order_line': 'NULL',
        })
        purchase_row = order_obj.browse(cr, uid, po_id, context=context)
        order_obj.write(cr, uid, po_id, {'state': 'draft'}, context=context)
        return po_id

    def create_move_sale_line(self, cr, uid, move, data_get, new_qty,
                              new_picking, pick_type_id, move_dest_id, pick, new_order_row, old_po_id,context=None):
        move_obj = self.pool.get('stock.move')
        purchase_line_obj = self.pool.get('purchase.order.line')
        purchase_line_id = purchase_line_obj.search(cr, uid, [('order_id', '=', old_po_id),
                                                              ('product_id', '=', data_get.product_id.id)
                                                              ],
                                                    context=context)
        purchase_line_row = purchase_line_obj.browse(cr, uid, purchase_line_id[0], context=context)
        po_line_id = purchase_line_obj.create(cr, uid, {
            'product_id': data_get.product_id.id,
            'product_qty': -new_qty,
            'name': data_get.product_id.name,
            'delivered_qty': new_qty,
            'order_id': new_order_row.id,
            'purchase_spec': move.note,
            'price_unit': purchase_line_row.price_unit,
            'state': 'draft',
            'date_planned': (datetime.now()).strftime(DEFAULT_SERVER_DATETIME_FORMAT)
        }, context=context)
        new_move_id = move_obj.copy(cr, SUPERUSER_ID, move.id, {
            'product_id': data_get.product_id.id,
            'product_uom_qty': new_qty,
            'product_uos_qty': new_qty * move.product_uos_qty / move.product_uom_qty,
            'picking_id': new_picking,
            'state': 'draft',
            'quant_ids': False,
            'po_id': purchase_line_row.order_id.id,
            'purchase_line_id': po_line_id,
            'origin': new_order_row.name,
            'location_id': move.location_dest_id.id,
            'location_dest_id': move.location_id.id,
            'picking_type_id': pick_type_id,
            'warehouse_id': pick.picking_type_id.warehouse_id.id,
            'origin_returned_move_id': move.id,
            'procure_method': 'make_to_stock',
            'move_dest_id': move_dest_id,
            'prod_spec': False,
        })
        move_obj.write(cr, uid, new_move_id, {'purchase_line_id': po_line_id}, context=context)
        return True

    def _create_returns(self, cr, uid, ids, context=None):
        if context is None:
            context = {}
        record_id = context and context.get('active_ids', False) or False
        move_obj = self.pool.get('stock.move')
        pick_obj = self.pool.get('stock.picking')
        order_row = self.pool.get('purchase.order').browse(cr, uid, record_id, context=context)
        data_obj = self.pool.get('return.move.line')
        picks = pick_obj.search(cr, SUPERUSER_ID,
                                [('po_id', 'in', record_id), ('picking_type_id.code', '=', 'incoming'),
                                 ('state', '=', 'done')],
                                context=context)
        pick_rows = pick_obj.browse(cr, SUPERUSER_ID, picks, context=context)
        data = self.read(cr, uid, ids[0], context=context)
        returned_lines, new_picking, move = 0, False, False
        po_id = self.create_return_purchase_order(cr, uid, order_row, context=context)
        new_order_row = self.pool.get('purchase.order').browse(cr, uid, po_id, context=context)
        common_picking_val = {
            'move_lines': [], 'state': 'draft', 'origin': new_order_row.name,
        }
        if new_order_row.partner_id.multi_address_ids:
            address = new_order_row.partner_id.multi_address_ids[0]
            common_picking_val.update({'consignee': address.name, 'street': address.street,
                                       'zip': address.zip, 'mobile_number': address.phone,
                                       'origin': new_order_row.name,
                                       'phone_number': address.phone_number, 'province_id': address.province_id.id,
                                       'city_id': address.city_id.id, 'county_id': address.county_id.id})
        for pick in pick_rows:
            moves_to_unreserve = []
            for move in pick.move_lines:
                to_check_moves = [move.move_dest_id] if move.move_dest_id.id else []
                while to_check_moves:
                    current_move = to_check_moves.pop()
                    if current_move.state not in ('done', 'cancel') and current_move.reserved_quant_ids:
                        moves_to_unreserve.append(current_move.id)
                    split_move_ids = move_obj.search(cr, uid, [('split_from', '=', current_move.id)],
                                                     context=context)
                    if split_move_ids:
                        to_check_moves += move_obj.browse(cr, uid, split_move_ids, context=context)
            if moves_to_unreserve:
                move_obj.do_unreserve(cr, uid, moves_to_unreserve, context=context)
                move_obj.write(cr, uid, moves_to_unreserve, {'move_orig_ids': False}, context=context)
            pick_type_id = pick.picking_type_id.return_picking_type_id and \
                           pick.picking_type_id.return_picking_type_id.id or pick.picking_type_id.id
            if not new_picking:
                common_picking_val.update({'picking_type_id': pick_type_id})
                new_picking = pick_obj.copy(cr, SUPERUSER_ID, pick.id,  common_picking_val, context=context)
        for data_get in data_obj.browse(cr, uid, data['product_return_moves'], context=context):
            move = data_get.move_id
            if not move:
                raise osv.except_osv(_(u'警告 !'), _(u"您已经手动生成了产品行，请删除他们并继续操作！"))
            new_qty = data_get.quantity
            if new_qty:
                if move.origin_returned_move_id.move_dest_id.id and \
                                move.origin_returned_move_id.move_dest_id.state != 'cancel':
                    move_dest_id = move.origin_returned_move_id.move_dest_id.id
                else:
                    move_dest_id = False
                returned_lines += 1
                self.create_move_sale_line(cr, uid, move, data_get, new_qty,
                                           new_picking, pick_type_id, move_dest_id, pick, new_order_row, order_row.id,
                                           context=context)
        # if move: # 没有实际意义但是影响原有的判断的功能，导致
        #     pick_obj.write(cr, uid, new_picking, {'origin_picking_id': move.picking_id.id}, context=context)
        if not returned_lines:
            raise osv.except_osv(_(u'警告!'), _(u"请保留至少一个非零的产品行！"))
        pick_obj.action_confirm(cr, SUPERUSER_ID, [new_picking], context=context)
        pick_obj.action_assign(cr, SUPERUSER_ID, [new_picking], context)
        return po_id

    def create_returns(self, cr, uid, ids, context=None):
        sale_id = self._create_returns(cr, uid, ids, context=context)
        return {
            'domain': "[('id', 'in', [" + str(sale_id) + "])]",
            'name': u'退货采购订单',
            'view_type': 'form',
            'view_mode': 'tree,form',
            'res_model': 'purchase.order',
            'type': 'ir.actions.act_window',
        }

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
